<!DOCTYPE html>
<!-- saved from url=(0052)https://www.cnblogs.com/zhuzhenwei918/p/7309604.html -->
<html lang="zh-cn" class="eye-protector-processed" style="background-color: rgb(193, 230, 198);"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="referrer" content="origin">
    <meta property="og:description" content="前言 什么是数据双向绑定？ vue是一个mvvm框架，即数据双向绑定，即当数据发生变化的时候，视图也就发生变化，当视图发生变化的时候，数据也会跟着同步变化。这也算是vue的精髓之处了。值得注意的是，我">
    <meta http-equiv="Cache-Control" content="no-transform">
    <meta http-equiv="Cache-Control" content="no-siteapp">
    <title>vue中的双向数据绑定详解 - Wayne-Zhu - 博客园</title>
    
    <link rel="stylesheet" href="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/blog-common.min.css">
    <link id="MainCss" rel="stylesheet" href="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/bundle-red_autumnal_leaves.min.css">
    
    <link id="mobile-style" media="only screen and (max-width: 767px)" type="text/css" rel="stylesheet" href="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/bundle-red_autumnal_leaves-mobile.min.css">
    
    <link type="application/rss+xml" rel="alternate" href="https://www.cnblogs.com/zhuzhenwei918/rss">
    <link type="application/rsd+xml" rel="EditURI" href="https://www.cnblogs.com/zhuzhenwei918/rsd.xml">
    <link type="application/wlwmanifest+xml" rel="wlwmanifest" href="https://www.cnblogs.com/zhuzhenwei918/wlwmanifest.xml">
    <script src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/amp4ads-host-v0.js.下载"></script><script src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/pubads_impl_rendering_2019082201.js.下载"></script><script async="" src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/analytics.js.下载"></script><script type="text/javascript" src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/encoder.js.下载"></script><script src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/jquery-2.2.0.min.js.下载"></script>
    <script src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/blog-common.min.js.下载"></script>
    <script>
        var currentBlogId = 311524;
        var currentBlogApp = 'zhuzhenwei918';
        var cb_enable_mathjax = false;
        var isLogined = false;
    </script>
    
    
    
<link rel="preload" href="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/f.txt" as="script"><script type="text/javascript" src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/f.txt"></script><link rel="preload" href="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/f(1).txt" as="script"><script type="text/javascript" src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/f(1).txt"></script><script src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/pubads_impl_2019082201.js.下载" async=""></script><link rel="prefetch" href="https://tpc.googlesyndication.com/safeframe/1-0-35/html/container.html"></head>
<body class="eye-protector-processed" style="background-color: rgb(193, 230, 198); transition: background-color 0.3s ease 0s;">
    <a name="top"></a>
    <div id="page_begin_html">
        <h3 style="padding: 8px; text-indent: 2em; display: none;" onclick="加油，保底BAT，争取SPECIAL！">曾经，我非常羡慕那些人见人爱的人，我也想要变成那样，可是后来我才明白人见人爱也是需要天赋的，后来我开始默默努力，我想，就算我不能让每个人都喜欢我，至少因为我做的努力能得到别人的尊重。</h3>
    </div>
    
<!--done-->
<div id="home">
<div id="header">
	<div id="blogTitle">
        <a id="lnkBlogLogo" href="https://www.cnblogs.com/zhuzhenwei918/"><img id="blogLogo" src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/logo.gif" alt="返回主页"></a>		
		
<!--done-->
<h1><a id="Header1_HeaderTitle" class="headermaintitle HeaderMainTitle" href="https://www.cnblogs.com/zhuzhenwei918/">Wayne  Zhu</a>
</h1>
<h2>
Keep looking, don't settle.
</h2>




		
	</div><!--end: blogTitle 博客的标题和副标题 -->
	<div id="navigator">
		
<ul id="navList">
<li><a id="blog_nav_sitehome" class="menu" href="https://www.cnblogs.com/">
博客园</a>
</li>
<li>
<a id="blog_nav_myhome" class="menu" href="https://www.cnblogs.com/zhuzhenwei918/">
首页</a>
</li>
<li>

<a id="blog_nav_newpost" class="menu" href="https://i.cnblogs.com/EditPosts.aspx?opt=1">
新随笔</a>
</li>
<li>
<a id="blog_nav_contact" class="menu" href="https://msg.cnblogs.com/send/Wayne-Zhu">
联系</a></li>
<li>

<!--<partial name="./Shared/_XmlLink.cshtml" model="Model" /></li>--></li>
<li>
<a id="blog_nav_admin" class="menu" href="https://i.cnblogs.com/">
管理</a>
</li>
</ul>


		<div class="blogStats">
			
			<span id="stats_post_count">随笔 - 
524&nbsp; </span>
<span id="stats_article_count">文章 - 
0&nbsp; </span>
<span id="stats-comment_count">评论 - 
240</span>

			
		</div><!--end: blogStats -->
	</div><!--end: navigator 博客导航栏 -->
</div><!--end: header 头部 -->

<div id="main">
	<div id="mainContent">
	<div class="forFlow">
		<div id="post_detail">
    <!--done-->
    <div id="topics">
        <div class="post">
            <h1 class="postTitle">
                
<a id="cb_post_title_url" class="postTitle2" href="https://www.cnblogs.com/zhuzhenwei918/p/7309604.html">vue中的双向数据绑定详解</a>

            </h1>
            <div class="clear"></div>
            <div class="postBody">
                
<div id="cnblogs_post_body" class="blogpost-body ">
    <p>&nbsp;</p>
<h2><strong>前言</strong></h2>
<p><strong>什么是数据双向绑定</strong>？&nbsp;</p>
<p>　　vue是一个mvvm框架，即数据双向绑定，即当数据发生变化的时候，视图也就发生变化，当视图发生变化的时候，数据也会跟着同步变化。这也算是vue的精髓之处了。<strong>值得注意的是，</strong>我们所说的数据双向绑定，一定是对于UI控件来说的，非UI控件不会涉及到数据双向绑定。 单向数据绑定是使用状态管理工具（如redux）的前提。如果我们使用vuex，那么数据流也是单项的，这时就会和双向数据绑定有冲突，<a href="https://github.com/vuejs/vuex/blob/master/docs/zh-cn/forms.md" target="_blank">我们可以这么解决</a>。&nbsp;</p>
<p>&nbsp;</p>
<p><strong>为什么要实现数据的双向绑定</strong>？</p>
<p>　　&nbsp;在vue中，如果使用vuex，实际上数据还是单向的，之所以说是数据双向绑定，这是用的UI控件来说，对于我们处理表单，vue的双向数据绑定用起来就特别舒服了。</p>
<p>　　&nbsp;<strong>即两者并不互斥， 在全局性数据流使用单项，方便跟踪； 局部性数据流使用双向，简单易操作。</strong></p>
<p>　　　</p>
<h2>一、访问器属性</h2>
<p>　　<a href="http://javascript.ruanyifeng.com/stdlib/attributes.html#toc2" target="_blank">Object.defineProperty()函数</a>可以定义对象的属性相关描述符， 其中的set和get函数对于完成数据双向绑定起到了至关重要的作用，下面，我们看看这个函数的基本使用方式。&nbsp;</p>
<p>　　</p>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div>
<pre>    <span style="color: #0000ff;">var</span> obj =<span style="color: #000000;"> {
      foo: </span><span style="color: #800000;">'</span><span style="color: #800000;">foo</span><span style="color: #800000;">'</span><span style="color: #000000;">
    }

    Object.defineProperty(obj, </span><span style="color: #800000;">'</span><span style="color: #800000;">foo</span><span style="color: #800000;">'</span><span style="color: #000000;">, {
      </span><span style="color: #0000ff;">get</span><span style="color: #000000;">: function () {
        console.log(</span><span style="color: #800000;">'</span><span style="color: #800000;">将要读取obj.foo属性</span><span style="color: #800000;">'</span><span style="color: #000000;">);
      }, 
      </span><span style="color: #0000ff;">set</span><span style="color: #000000;">: function (newVal) {
        console.log(</span><span style="color: #800000;">'</span><span style="color: #800000;">当前值为</span><span style="color: #800000;">'</span><span style="color: #000000;">, newVal);
      }
    });

    obj.foo; </span><span style="color: #008000;">//</span><span style="color: #008000;"> 将要读取obj.foo属性</span>
    obj.foo = <span style="color: #800000;">'</span><span style="color: #800000;">name</span><span style="color: #800000;">'</span>; <span style="color: #008000;">//</span><span style="color: #008000;"> 当前值为 name</span></pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div></div>
<p>&nbsp;</p>
<p>　　可以看到，get即为我们访问属性时调用，set为我们设置属性值时调用。</p>
<p>&nbsp;</p>
<p>　　</p>
<h2>二、简单的数据双向绑定实现方法</h2>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div>
<pre>&lt;!DOCTYPE html&gt;
&lt;html lang=<span style="color: #800000;">"</span><span style="color: #800000;">en</span><span style="color: #800000;">"</span>&gt;
&lt;head&gt;
  &lt;meta charset=<span style="color: #800000;">"</span><span style="color: #800000;">UTF-8</span><span style="color: #800000;">"</span>&gt;
  &lt;title&gt;forvue&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;input type=<span style="color: #800000;">"</span><span style="color: #800000;">text</span><span style="color: #800000;">"</span> id=<span style="color: #800000;">"</span><span style="color: #800000;">textInput</span><span style="color: #800000;">"</span>&gt;<span style="color: #000000;">
  输入：</span>&lt;span id=<span style="color: #800000;">"</span><span style="color: #800000;">textSpan</span><span style="color: #800000;">"</span>&gt;&lt;/span&gt;
  &lt;script&gt;
    <span style="color: #0000ff;">var</span> obj =<span style="color: #000000;"> {},
        textInput </span>= document.querySelector(<span style="color: #800000;">'</span><span style="color: #800000;">#textInput</span><span style="color: #800000;">'</span><span style="color: #000000;">),
        textSpan </span>= document.querySelector(<span style="color: #800000;">'</span><span style="color: #800000;">#textSpan</span><span style="color: #800000;">'</span><span style="color: #000000;">);

    Object.defineProperty(obj, </span><span style="color: #800000;">'</span><span style="color: #800000;">foo</span><span style="color: #800000;">'</span><span style="color: #000000;">, {
      </span><span style="color: #0000ff;">set</span><span style="color: #000000;">: function (newValue) {
        textInput.value </span>=<span style="color: #000000;"> newValue;
        textSpan.innerHTML </span>=<span style="color: #000000;"> newValue;
      }
    });

    textInput.addEventListener(</span><span style="color: #800000;">'</span><span style="color: #800000;">keyup</span><span style="color: #800000;">'</span><span style="color: #000000;">, function (e) {
        obj.foo </span>=<span style="color: #000000;"> e.target.value;
    });

  </span>&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div></div>
<p>&nbsp;</p>
<p>最终效果图：</p>
<p><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/1044137-20170825145431808-435745456.png" alt=""></p>
<p>&nbsp;</p>
<p>可以看到，实现一个简单的数据双向绑定还是不难的： 使用Object.defineProperty()来定义属性的set函数，属性被赋值的时候，修改Input的value值以及span中的innerHTML；然后监听input的keyup事件，修改对象的属性值，即可实现这样的一个简单的数据双向绑定。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>三、 实现任务的思路</h2>
<p>　　上面我们只是实现了一个最简单的数据双向绑定，而我们真正希望实现的时下面这种方式：</p>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div>
<pre>    &lt;div id=<span style="color: #800000;">"</span><span style="color: #800000;">app</span><span style="color: #800000;">"</span>&gt;
        &lt;input type=<span style="color: #800000;">"</span><span style="color: #800000;">text</span><span style="color: #800000;">"</span> v-model=<span style="color: #800000;">"</span><span style="color: #800000;">text</span><span style="color: #800000;">"</span>&gt;<span style="color: #000000;">
        {{ text }}
    </span>&lt;/div&gt;  

    &lt;script&gt;
        <span style="color: #0000ff;">var</span> vm = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Vue({
            el: </span><span style="color: #800000;">'</span><span style="color: #800000;">#app</span><span style="color: #800000;">'</span><span style="color: #000000;">, 
            data: {
                text: </span><span style="color: #800000;">'</span><span style="color: #800000;">hello world</span><span style="color: #800000;">'</span><span style="color: #000000;">
            }
        });
    </span>&lt;/script&gt;</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div></div>
<p>　　即和vue一样的方式来实现数据的双向绑定。那么，<strong>我们可以把整个实现过程分为下面几步：&nbsp;</strong></p>
<ul>
<li>输入框以及文本节点与 data 中的数据<strong>绑定</strong></li>
<li>输入框内容变化时，data 中的数据同步变化。即 <strong>view =&gt; model 的变化</strong>。</li>
<li>data 中的数据变化时，文本节点的内容同步变化。即 <strong>model =&gt; view 的变化</strong>。</li>
</ul>
<p>　　</p>
<p>&nbsp;</p>
<h2>四、DocumentFragment</h2>
<p>　　如果希望实现任务一，我们还需要使用到 DocumentFragment 文档片段，可以把它看做一个容器，如下所示：</p>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div>
<pre>&lt;div id=<span style="color: #800000;">"</span><span style="color: #800000;">app</span><span style="color: #800000;">"</span>&gt;
        
    &lt;/div&gt;
    &lt;script&gt;
        <span style="color: #0000ff;">var</span> flag =<span style="color: #000000;"> document.createDocumentFragment(),
            span </span>= document.createElement(<span style="color: #800000;">'</span><span style="color: #800000;">span</span><span style="color: #800000;">'</span><span style="color: #000000;">),
            textNode </span>= document.createTextNode(<span style="color: #800000;">'</span><span style="color: #800000;">hello world</span><span style="color: #800000;">'</span><span style="color: #000000;">);
        span.appendChild(textNode);
        flag.appendChild(span);
        document.querySelector(</span><span style="color: #800000;">'</span><span style="color: #800000;">#app</span><span style="color: #800000;">'</span><span style="color: #000000;">).appendChild(flag)
    </span>&lt;/script&gt;</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div></div>
<p>　　这样，我们就可以得到下面的DOM树：</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp;<img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/1044137-20170825151130871-477199008.png" alt=""></p>
<p>　　使用文档片段的好处在于：在文档片段上进行操作DOM，而不会影响到真实的DOM，操作完成之后，我们就可以添加到真实DOM上，这样的效率比直接在正式DOM上修改要高很多 。</p>
<p>&nbsp;</p>
<p>　　<strong>vue进行编译时，就是将挂载目标的所有子节点劫持到DocumentFragment中，经过一番处理之后，再将DocumentFragment整体返回插入挂载目标</strong>。 &nbsp;</p>
<p>　　<strong>&nbsp;</strong></p>
<p><strong>　　</strong>如下所示<strong>：</strong></p>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div>
<pre>&lt;!DOCTYPE html&gt;
&lt;html lang=<span style="color: #800000;">"</span><span style="color: #800000;">en</span><span style="color: #800000;">"</span>&gt;
&lt;head&gt;
  &lt;meta charset=<span style="color: #800000;">"</span><span style="color: #800000;">UTF-8</span><span style="color: #800000;">"</span>&gt;
  &lt;title&gt;forvue&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div id=<span style="color: #800000;">"</span><span style="color: #800000;">app</span><span style="color: #800000;">"</span>&gt;
        &lt;input type=<span style="color: #800000;">"</span><span style="color: #800000;">text</span><span style="color: #800000;">"</span> id=<span style="color: #800000;">"</span><span style="color: #800000;">a</span><span style="color: #800000;">"</span>&gt;
        &lt;span id=<span style="color: #800000;">"</span><span style="color: #800000;">b</span><span style="color: #800000;">"</span>&gt;&lt;/span&gt;
    &lt;/div&gt;

    &lt;script&gt;
        <span style="color: #0000ff;">var</span> dom = nodeToFragment(document.getElementById(<span style="color: #800000;">'</span><span style="color: #800000;">app</span><span style="color: #800000;">'</span><span style="color: #000000;">));
        console.log(dom);

        function nodeToFragment(node) {
            </span><span style="color: #0000ff;">var</span> flag =<span style="color: #000000;"> document.createDocumentFragment();
            </span><span style="color: #0000ff;">var</span><span style="color: #000000;"> child;
            </span><span style="color: #0000ff;">while</span> (child =<span style="color: #000000;"> node.firstChild) {
                flag.appendChild(child);
            }
            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> flag;
        }

        document.getElementById(</span><span style="color: #800000;">'</span><span style="color: #800000;">app</span><span style="color: #800000;">'</span><span style="color: #000000;">).appendChild(dom);
    </span>&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div></div>
<p>&nbsp;即首先获取到div，然后通过documentFragment劫持，接着再把这个文档片段添加到div上去。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>五、初始化数据绑定</h2>
<p>　　</p>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div>
<pre>&lt;!DOCTYPE html&gt;
&lt;html lang=<span style="color: #800000;">"</span><span style="color: #800000;">en</span><span style="color: #800000;">"</span>&gt;
&lt;head&gt;
  &lt;meta charset=<span style="color: #800000;">"</span><span style="color: #800000;">UTF-8</span><span style="color: #800000;">"</span>&gt;
  &lt;title&gt;forvue&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div id=<span style="color: #800000;">"</span><span style="color: #800000;">app</span><span style="color: #800000;">"</span>&gt;
        &lt;input type=<span style="color: #800000;">"</span><span style="color: #800000;">text</span><span style="color: #800000;">"</span> v-model=<span style="color: #800000;">"</span><span style="color: #800000;">text</span><span style="color: #800000;">"</span>&gt;<span style="color: #000000;">
        {{ text }}
    </span>&lt;/div&gt;
        
    &lt;script&gt;<span style="color: #000000;">
        function compile(node, vm) {
            </span><span style="color: #0000ff;">var</span> reg = /\{\{(.*)\}\}/<span style="color: #000000;">;

            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 节点类型为元素</span>
            <span style="color: #0000ff;">if</span> (node.nodeType === <span style="color: #800080;">1</span><span style="color: #000000;">) {
                </span><span style="color: #0000ff;">var</span> attr =<span style="color: #000000;"> node.attributes;
                </span><span style="color: #008000;">//</span><span style="color: #008000;"> 解析属性</span>
                <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> i = <span style="color: #800080;">0</span>; i &lt; attr.length; i++<span style="color: #000000;">) {
                    </span><span style="color: #0000ff;">if</span> (attr[i].nodeName == <span style="color: #800000;">'</span><span style="color: #800000;">v-model</span><span style="color: #800000;">'</span><span style="color: #000000;">) {
                        </span><span style="color: #0000ff;">var</span> name = attr[i].nodeValue; <span style="color: #008000;">//</span><span style="color: #008000;"> 获取v-model绑定的属性名</span>
                        node.value = vm.data[name]; <span style="color: #008000;">//</span><span style="color: #008000;"> 将data的值赋值给该node</span>
                        node.removeAttribute(<span style="color: #800000;">'</span><span style="color: #800000;">v-model</span><span style="color: #800000;">'</span><span style="color: #000000;">);
                    }
                }
            }

            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 节点类型为text</span>
            <span style="color: #0000ff;">if</span> (node.nodeType === <span style="color: #800080;">3</span><span style="color: #000000;">) {
                </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (reg.test(node.nodeValue)) {
                    </span><span style="color: #0000ff;">var</span> name = RegExp.$<span style="color: #800080;">1</span>; <span style="color: #008000;">//</span><span style="color: #008000;"> 获取匹配到的字符串</span>
                    name =<span style="color: #000000;"> name.trim();
                    node.nodeValue </span>= vm.data[name]; <span style="color: #008000;">//</span><span style="color: #008000;"> 将data的值赋值给该node</span>
<span style="color: #000000;">                }
            }
        }

        function nodeToFragment(node, vm) {
            </span><span style="color: #0000ff;">var</span> flag =<span style="color: #000000;"> document.createDocumentFragment();
            </span><span style="color: #0000ff;">var</span><span style="color: #000000;"> child;

            </span><span style="color: #0000ff;">while</span> (child =<span style="color: #000000;"> node.firstChild) {
                compile(child, vm);
                flag.appendChild(child); </span><span style="color: #008000;">//</span><span style="color: #008000;"> 将子节点劫持到文档片段中</span>
<span style="color: #000000;">            }
            
            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> flag;
        }

        function Vue(options) {
            </span><span style="color: #0000ff;">this</span>.data =<span style="color: #000000;"> options.data;
            </span><span style="color: #0000ff;">var</span> id =<span style="color: #000000;"> options.el;
            </span><span style="color: #0000ff;">var</span> dom = nodeToFragment(document.getElementById(id), <span style="color: #0000ff;">this</span><span style="color: #000000;">);
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 编译完成后，将dom返回到app中。</span>
<span style="color: #000000;">            document.getElementById(id).appendChild(dom);
        }

        </span><span style="color: #0000ff;">var</span> vm  = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Vue({
            el: </span><span style="color: #800000;">'</span><span style="color: #800000;">app</span><span style="color: #800000;">'</span><span style="color: #000000;">,
            data: {
                text: </span><span style="color: #800000;">'</span><span style="color: #800000;">hello world</span><span style="color: #800000;">'</span><span style="color: #000000;">
            }
        });


    </span>&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div></div>
<p>&nbsp;</p>
<p>以上的代码实现而立任务一，我们可以看到，hello world 已经呈现在了输入框和文本节点中了。&nbsp;</p>
<p>&nbsp;</p>
<p><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/1044137-20170825155926933-1355261671.png" alt=""></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>六、响应式的数据绑定</h2>
<p>　　我们再来看看任务二的实现思路： 当我们在输入框输入数据的时候，首先触发的时input事件（或者keyup、change事件），在相应的事件处理程序中，我们获取输入框的value并赋值给vm实例的text属性。 我们会利用defineProperty将data中的text设置为vm的访问器属性，因此给vm.text赋值，就会触发set方法。 在set方法中主要做两件事情，第一是<strong>更新属性的值</strong>，第二留在任务三种说。</p>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div>
<pre>&lt;!DOCTYPE html&gt;
&lt;html lang=<span style="color: #800000;">"</span><span style="color: #800000;">en</span><span style="color: #800000;">"</span>&gt;
&lt;head&gt;
  &lt;meta charset=<span style="color: #800000;">"</span><span style="color: #800000;">UTF-8</span><span style="color: #800000;">"</span>&gt;
  &lt;title&gt;forvue&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div id=<span style="color: #800000;">"</span><span style="color: #800000;">app</span><span style="color: #800000;">"</span>&gt;
        &lt;input type=<span style="color: #800000;">"</span><span style="color: #800000;">text</span><span style="color: #800000;">"</span> v-model=<span style="color: #800000;">"</span><span style="color: #800000;">text</span><span style="color: #800000;">"</span>&gt;<span style="color: #000000;">
        {{ text }}
    </span>&lt;/div&gt;
        
    &lt;script&gt;<span style="color: #000000;">
        function compile(node, vm) {
            </span><span style="color: #0000ff;">var</span> reg = /\{\{(.*)\}\}/<span style="color: #000000;">;

            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 节点类型为元素</span>
            <span style="color: #0000ff;">if</span> (node.nodeType === <span style="color: #800080;">1</span><span style="color: #000000;">) {
                </span><span style="color: #0000ff;">var</span> attr =<span style="color: #000000;"> node.attributes;
                </span><span style="color: #008000;">//</span><span style="color: #008000;"> 解析属性</span>
                <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> i = <span style="color: #800080;">0</span>; i &lt; attr.length; i++<span style="color: #000000;">) {
                    </span><span style="color: #0000ff;">if</span> (attr[i].nodeName == <span style="color: #800000;">'</span><span style="color: #800000;">v-model</span><span style="color: #800000;">'</span><span style="color: #000000;">) {
                        </span><span style="color: #0000ff;">var</span> name = attr[i].nodeValue; <span style="color: #008000;">//</span><span style="color: #008000;"> 获取v-model绑定的属性名</span>
                        node.addEventListener(<span style="color: #800000;">'</span><span style="color: #800000;">input</span><span style="color: #800000;">'</span><span style="color: #000000;">, function (e) {
                            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 给相应的data属性赋值，进而触发属性的set方法</span>
                            vm[name] =<span style="color: #000000;"> e.target.value;
                        })


                        node.value </span>= vm[name]; <span style="color: #008000;">//</span><span style="color: #008000;"> 将data的值赋值给该node</span>
                        node.removeAttribute(<span style="color: #800000;">'</span><span style="color: #800000;">v-model</span><span style="color: #800000;">'</span><span style="color: #000000;">);
                    }
                }
            }

            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 节点类型为text</span>
            <span style="color: #0000ff;">if</span> (node.nodeType === <span style="color: #800080;">3</span><span style="color: #000000;">) {
                </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (reg.test(node.nodeValue)) {
                    </span><span style="color: #0000ff;">var</span> name = RegExp.$<span style="color: #800080;">1</span>; <span style="color: #008000;">//</span><span style="color: #008000;"> 获取匹配到的字符串</span>
                    name =<span style="color: #000000;"> name.trim();
                    node.nodeValue </span>= vm[name]; <span style="color: #008000;">//</span><span style="color: #008000;"> 将data的值赋值给该node</span>
<span style="color: #000000;">                }
            }
        }

        function nodeToFragment(node, vm) {
            </span><span style="color: #0000ff;">var</span> flag =<span style="color: #000000;"> document.createDocumentFragment();
            </span><span style="color: #0000ff;">var</span><span style="color: #000000;"> child;

            </span><span style="color: #0000ff;">while</span> (child =<span style="color: #000000;"> node.firstChild) {
                compile(child, vm);
                flag.appendChild(child); </span><span style="color: #008000;">//</span><span style="color: #008000;"> 将子节点劫持到文档片段中</span>
<span style="color: #000000;">            }
            
            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> flag;
        }

        function Vue(options) {
            </span><span style="color: #0000ff;">this</span>.data =<span style="color: #000000;"> options.data;
            </span><span style="color: #0000ff;">var</span> data = <span style="color: #0000ff;">this</span><span style="color: #000000;">.data;

            observe(data, </span><span style="color: #0000ff;">this</span><span style="color: #000000;">);

            </span><span style="color: #0000ff;">var</span> id =<span style="color: #000000;"> options.el;
            </span><span style="color: #0000ff;">var</span> dom = nodeToFragment(document.getElementById(id), <span style="color: #0000ff;">this</span><span style="color: #000000;">);
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 编译完成后，将dom返回到app中。</span>
<span style="color: #000000;">            document.getElementById(id).appendChild(dom);
        }

        </span><span style="color: #0000ff;">var</span> vm  = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Vue({
            el: </span><span style="color: #800000;">'</span><span style="color: #800000;">app</span><span style="color: #800000;">'</span><span style="color: #000000;">,
            data: {
                text: </span><span style="color: #800000;">'</span><span style="color: #800000;">hello world</span><span style="color: #800000;">'</span><span style="color: #000000;">
            }
        });



        function defineReactive(obj, key, val) {
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 响应式的数据绑定</span>
<span style="color: #000000;">            Object.defineProperty(obj, key, {
                </span><span style="color: #0000ff;">get</span><span style="color: #000000;">: function () {
                    </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> val;
                },
                </span><span style="color: #0000ff;">set</span><span style="color: #000000;">: function (newVal) {
                    </span><span style="color: #0000ff;">if</span> (newVal ===<span style="color: #000000;"> val) {
                        </span><span style="color: #0000ff;">return</span><span style="color: #000000;">; 
                    } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {
                        val </span>=<span style="color: #000000;"> newVal;
                        console.log(val); </span><span style="color: #008000;">//</span><span style="color: #008000;"> 方便看效果</span>
<span style="color: #000000;">                    }
                }
            });
        }

        function observe (obj, vm) {
            Object.keys(obj).forEach(function (key) {
                defineReactive(vm, key, obj[key]);
            });
        }


    </span>&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div></div>
<p>以上，任务二也就完成了，text属性值会和输入框的内容同步变化。</p>
<p>&nbsp;</p>
<h2>&nbsp;</h2>
<h2>七、 订阅/发布模式（subscribe &amp; publish）</h2>
<p>　　text属性变化了，set方法触发了，但是文本节点的内容没有变化。 如何才能让同样绑定到text的文本节点也同步变化呢？ 这里又有一个知识点： 订阅发布模式。</p>
<p>　　订阅发布模式又称为观察者模式，<strong>定义了一种一对多的关系</strong>，<strong>让多个观察者同时监听某一个主题对象</strong>，这个主题对象的状态发生改变时就会通知所有的观察者对象。&nbsp;</p>
<p>　　<strong>发布者发出通知</strong> =&gt;<strong>主题对象收到通知</strong>并<strong>推送给订阅者 =&gt; 订阅者执行相应的操作。&nbsp;</strong></p>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div>
<pre> <span style="color: #008000;">//</span><span style="color: #008000;"> 一个发布者 publisher，功能就是负责发布消息 - publish</span>
        <span style="color: #0000ff;">var</span> pub =<span style="color: #000000;"> {
            publish: function () {
                dep.notify();
            }
        }

        </span><span style="color: #008000;">//</span><span style="color: #008000;"> 多个订阅者 subscribers， 在发布者发布消息之后执行函数</span>
        <span style="color: #0000ff;">var</span> sub1 =<span style="color: #000000;"> { 
            update: function () {
                console.log(</span><span style="color: #800080;">1</span><span style="color: #000000;">);
            }
        }
        </span><span style="color: #0000ff;">var</span> sub2 =<span style="color: #000000;"> { 
            update: function () {
                console.log(</span><span style="color: #800080;">2</span><span style="color: #000000;">);
            }
        }
        </span><span style="color: #0000ff;">var</span> sub3 =<span style="color: #000000;"> { 
            update: function () {
                console.log(</span><span style="color: #800080;">3</span><span style="color: #000000;">);
            }
        }

        </span><span style="color: #008000;">//</span><span style="color: #008000;"> 一个主题对象</span>
<span style="color: #000000;">        function Dep() {
            </span><span style="color: #0000ff;">this</span>.subs =<span style="color: #000000;"> [sub1, sub2, sub3];
        }
        Dep.prototype.notify </span>=<span style="color: #000000;"> function () {
            </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.subs.forEach(function (sub) {
                sub.update();
            });
        }


        </span><span style="color: #008000;">//</span><span style="color: #008000;"> 发布者发布消息， 主题对象执行notify方法，进而触发订阅者执行Update方法</span>
        <span style="color: #0000ff;">var</span> dep = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Dep();
        pub.publish();</span></pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div></div>
<p>不难看出，这里的思路还是很简单的： 发布者负责发布消息、 订阅者负责接收接收消息，而最重要的是主题对象，他需要记录所有的订阅这特消息的人，然后负责吧发布的消息通知给哪些订阅了消息的人。</p>
<p>所以，当set方法触发后做的第二件事情就是作为发布者发出通知： “我是属性text，我变了”。 文本节点作为订阅者，在接收到消息之后执行相应的更新动作。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>八、 双向绑定的实现</h2>
<p>　　回顾一下，每当new一个Vue，主要做了两件事情：第一是监听数据：observe(data)，第二是编译HTML：nodeToFragment(id)</p>
<p>　　在监听数据的过程中，会为data中的每一个属性生成一个主题对象dep。&nbsp;</p>
<p>　　在编译HTML的过程中，会为每一个与数据绑定相关的节点生成一个订阅者 watcher，watcher会将自己添加到相应属性的dep中。&nbsp;</p>
<p>　　我们已经实现了： 修改输入框内容 =&gt; 在事件回调函数中修改属性值 =&gt; 触发属性的set方法。</p>
<p>　　接下来我们要实现的是： 发出通知 dep.notify() =&gt; 触发订阅者update方法 =&gt; 更新视图。</p>
<p>　　这里的关键逻辑是： 如何将watcher添加到关联属性的dep中。</p>
<p>&nbsp;</p>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div>
<pre><span style="color: #000000;">        function compile(node, vm) {
            </span><span style="color: #0000ff;">var</span> reg = /\{\{(.*)\}\}/<span style="color: #000000;">;

            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 节点类型为元素</span>
            <span style="color: #0000ff;">if</span> (node.nodeType === <span style="color: #800080;">1</span><span style="color: #000000;">) {
                </span><span style="color: #0000ff;">var</span> attr =<span style="color: #000000;"> node.attributes;
                </span><span style="color: #008000;">//</span><span style="color: #008000;"> 解析属性</span>
                <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> i = <span style="color: #800080;">0</span>; i &lt; attr.length; i++<span style="color: #000000;">) {
                    </span><span style="color: #0000ff;">if</span> (attr[i].nodeName == <span style="color: #800000;">'</span><span style="color: #800000;">v-model</span><span style="color: #800000;">'</span><span style="color: #000000;">) {
                        </span><span style="color: #0000ff;">var</span> name = attr[i].nodeValue; <span style="color: #008000;">//</span><span style="color: #008000;"> 获取v-model绑定的属性名</span>
                        node.addEventListener(<span style="color: #800000;">'</span><span style="color: #800000;">input</span><span style="color: #800000;">'</span><span style="color: #000000;">, function (e) {
                            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 给相应的data属性赋值，进而触发属性的set方法</span>
                            vm[name] =<span style="color: #000000;"> e.target.value;
                        })


                        node.value </span>= vm[name]; <span style="color: #008000;">//</span><span style="color: #008000;"> 将data的值赋值给该node</span>
                        node.removeAttribute(<span style="color: #800000;">'</span><span style="color: #800000;">v-model</span><span style="color: #800000;">'</span><span style="color: #000000;">);
                    }
                }
            }

            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 节点类型为text</span>
            <span style="color: #0000ff;">if</span> (node.nodeType === <span style="color: #800080;">3</span><span style="color: #000000;">) {
                </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (reg.test(node.nodeValue)) {
                    </span><span style="color: #0000ff;">var</span> name = RegExp.$<span style="color: #800080;">1</span>; <span style="color: #008000;">//</span><span style="color: #008000;"> 获取匹配到的字符串</span>
                    name =<span style="color: #000000;"> name.trim();
                    </span><span style="color: #008000;">//</span><span style="color: #008000;"> node.nodeValue = vm[name]; </span><span style="color: #008000;">//</span><span style="color: #008000;"> 将data的值赋值给该node</span>

                    <span style="color: #0000ff;">new</span><span style="color: #000000;"> Watcher(vm, node, name);
                }
            }
        }</span></pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div></div>
<p>&nbsp;</p>
<p>在编译HTML的过程中，为每个和data关联的节点生成一个Watcher。那么Watcher函数中发生了什么呢？</p>
<p>&nbsp;</p>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div>
<pre><span style="color: #000000;">    function Watcher(vm, node, name) {
            Dep.target </span>= <span style="color: #0000ff;">this</span><span style="color: #000000;">;
            </span><span style="color: #0000ff;">this</span>.name =<span style="color: #000000;"> name;
            </span><span style="color: #0000ff;">this</span>.node =<span style="color: #000000;"> node;
            </span><span style="color: #0000ff;">this</span>.vm =<span style="color: #000000;"> vm;
            </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.update();
            Dep.target </span>= <span style="color: #0000ff;">null</span><span style="color: #000000;">;
        }

        Watcher.prototype </span>=<span style="color: #000000;"> {
            update: function () {
                </span><span style="color: #0000ff;">this</span>.<span style="color: #0000ff;">get</span><span style="color: #000000;">();
                </span><span style="color: #0000ff;">this</span>.node.nodeValue = <span style="color: #0000ff;">this</span><span style="color: #000000;">.value;
            },

            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 获取data中的属性值</span>
            <span style="color: #0000ff;">get</span><span style="color: #000000;">: function () {
                </span><span style="color: #0000ff;">this</span>.value = <span style="color: #0000ff;">this</span>.vm[<span style="color: #0000ff;">this</span>.name]; <span style="color: #008000;">//</span><span style="color: #008000;"> 触发相应属性的get</span>
<span style="color: #000000;">            }
        }</span></pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div></div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>首先，将自己赋值给了一个全局变量 Dep.target;</p>
<p>其次，执行了update方法，进而执行了 get 方法，get方法读取了vm的访问器属性， 从而触发了访问器属性的get方法，get方法将该watcher添加到对应访问器属性的dep中；</p>
<p>再次，获取顺序性的值， 然后更新视图。</p>
<p>最后将Dep.target设置为空。 因为他是全局变量，也是watcher和dep关联的唯一桥梁，任何时候，都必须保证Dep.target只有一个值。</p>
<p>&nbsp;</p>
<p>最终如下：</p>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div>
<pre>&lt;!DOCTYPE html&gt;
&lt;html lang=<span style="color: #800000;">"</span><span style="color: #800000;">en</span><span style="color: #800000;">"</span>&gt;
&lt;head&gt;
  &lt;meta charset=<span style="color: #800000;">"</span><span style="color: #800000;">UTF-8</span><span style="color: #800000;">"</span>&gt;
  &lt;title&gt;forvue&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div id=<span style="color: #800000;">"</span><span style="color: #800000;">app</span><span style="color: #800000;">"</span>&gt;
        &lt;input type=<span style="color: #800000;">"</span><span style="color: #800000;">text</span><span style="color: #800000;">"</span> v-model=<span style="color: #800000;">"</span><span style="color: #800000;">text</span><span style="color: #800000;">"</span>&gt; &lt;br&gt;<span style="color: #000000;">
        {{ text }} </span>&lt;br&gt;<span style="color: #000000;">
        {{ text }}
    </span>&lt;/div&gt;
        
    &lt;script&gt;<span style="color: #000000;">
        function observe(obj, vm) {
            Object.keys(obj).forEach(function (key) {
                defineReactive(vm, key, obj[key]);
            });
        }


        function defineReactive(obj, key, val) {

            </span><span style="color: #0000ff;">var</span> dep = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Dep();

            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 响应式的数据绑定</span>
<span style="color: #000000;">            Object.defineProperty(obj, key, {
                </span><span style="color: #0000ff;">get</span><span style="color: #000000;">: function () {
                    </span><span style="color: #008000;">//</span><span style="color: #008000;"> 添加订阅者watcher到主题对象Dep</span>
                    <span style="color: #0000ff;">if</span><span style="color: #000000;"> (Dep.target) {
                        dep.addSub(Dep.target);
                    }
                    </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> val;
                },
                </span><span style="color: #0000ff;">set</span><span style="color: #000000;">: function (newVal) {
                    </span><span style="color: #0000ff;">if</span> (newVal ===<span style="color: #000000;"> val) {
                        </span><span style="color: #0000ff;">return</span><span style="color: #000000;">; 
                    } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {
                        val </span>=<span style="color: #000000;"> newVal;
                        </span><span style="color: #008000;">//</span><span style="color: #008000;"> 作为发布者发出通知</span>
<span style="color: #000000;">                        dep.notify()                        
                    }
                }
            });
        }
        
        function nodeToFragment(node, vm) {
            </span><span style="color: #0000ff;">var</span> flag =<span style="color: #000000;"> document.createDocumentFragment();
            </span><span style="color: #0000ff;">var</span><span style="color: #000000;"> child;

            </span><span style="color: #0000ff;">while</span> (child =<span style="color: #000000;"> node.firstChild) {
                compile(child, vm);
                flag.appendChild(child); </span><span style="color: #008000;">//</span><span style="color: #008000;"> 将子节点劫持到文档片段中</span>
<span style="color: #000000;">            }
            
            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> flag;
        }

        function compile(node, vm) {
            </span><span style="color: #0000ff;">var</span> reg = /\{\{(.*)\}\}/<span style="color: #000000;">;

            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 节点类型为元素</span>
            <span style="color: #0000ff;">if</span> (node.nodeType === <span style="color: #800080;">1</span><span style="color: #000000;">) {
                </span><span style="color: #0000ff;">var</span> attr =<span style="color: #000000;"> node.attributes;
                </span><span style="color: #008000;">//</span><span style="color: #008000;"> 解析属性</span>
                <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> i = <span style="color: #800080;">0</span>; i &lt; attr.length; i++<span style="color: #000000;">) {
                    </span><span style="color: #0000ff;">if</span> (attr[i].nodeName == <span style="color: #800000;">'</span><span style="color: #800000;">v-model</span><span style="color: #800000;">'</span><span style="color: #000000;">) {
                        </span><span style="color: #0000ff;">var</span> name = attr[i].nodeValue; <span style="color: #008000;">//</span><span style="color: #008000;"> 获取v-model绑定的属性名</span>
                        node.addEventListener(<span style="color: #800000;">'</span><span style="color: #800000;">input</span><span style="color: #800000;">'</span><span style="color: #000000;">, function (e) {
                            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 给相应的data属性赋值，进而触发属性的set方法</span>
                            vm[name] =<span style="color: #000000;"> e.target.value;
                        })
                        node.value </span>= vm[name]; <span style="color: #008000;">//</span><span style="color: #008000;"> 将data的值赋值给该node</span>
                        node.removeAttribute(<span style="color: #800000;">'</span><span style="color: #800000;">v-model</span><span style="color: #800000;">'</span><span style="color: #000000;">);
                    }
                }
            }

            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 节点类型为text</span>
            <span style="color: #0000ff;">if</span> (node.nodeType === <span style="color: #800080;">3</span><span style="color: #000000;">) {
                </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (reg.test(node.nodeValue)) {
                    </span><span style="color: #0000ff;">var</span> name = RegExp.$<span style="color: #800080;">1</span>; <span style="color: #008000;">//</span><span style="color: #008000;"> 获取匹配到的字符串</span>
                    name =<span style="color: #000000;"> name.trim();
                    </span><span style="color: #008000;">//</span><span style="color: #008000;"> node.nodeValue = vm[name]; </span><span style="color: #008000;">//</span><span style="color: #008000;"> 将data的值赋值给该node</span>

                    <span style="color: #0000ff;">new</span><span style="color: #000000;"> Watcher(vm, node, name);
                }
            }
        }

        function Watcher(vm, node, name) {
            Dep.target </span>= <span style="color: #0000ff;">this</span><span style="color: #000000;">;
            </span><span style="color: #0000ff;">this</span>.name =<span style="color: #000000;"> name;
            </span><span style="color: #0000ff;">this</span>.node =<span style="color: #000000;"> node;
            </span><span style="color: #0000ff;">this</span>.vm =<span style="color: #000000;"> vm;
            </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.update();
            Dep.target </span>= <span style="color: #0000ff;">null</span><span style="color: #000000;">;
        }

        Watcher.prototype </span>=<span style="color: #000000;"> {
            update: function () {
                </span><span style="color: #0000ff;">this</span>.<span style="color: #0000ff;">get</span><span style="color: #000000;">();
                </span><span style="color: #0000ff;">this</span>.node.nodeValue = <span style="color: #0000ff;">this</span><span style="color: #000000;">.value;
            },

            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 获取data中的属性值</span>
            <span style="color: #0000ff;">get</span><span style="color: #000000;">: function () {
                </span><span style="color: #0000ff;">this</span>.value = <span style="color: #0000ff;">this</span>.vm[<span style="color: #0000ff;">this</span>.name]; <span style="color: #008000;">//</span><span style="color: #008000;"> 触发相应属性的get</span>
<span style="color: #000000;">            }
        }

        function Dep () {
            </span><span style="color: #0000ff;">this</span>.subs =<span style="color: #000000;"> [];
        }

        Dep.prototype </span>=<span style="color: #000000;"> {
            addSub: function (sub) {
                </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.subs.push(sub);
            },

            notify: function () {
                </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.subs.forEach(function (sub) {
                    sub.update();
                });
            }
        }

        function Vue(options) {
            </span><span style="color: #0000ff;">this</span>.data =<span style="color: #000000;"> options.data;
            </span><span style="color: #0000ff;">var</span> data = <span style="color: #0000ff;">this</span><span style="color: #000000;">.data;

            observe(data, </span><span style="color: #0000ff;">this</span><span style="color: #000000;">);

            </span><span style="color: #0000ff;">var</span> id =<span style="color: #000000;"> options.el;
            </span><span style="color: #0000ff;">var</span> dom = nodeToFragment(document.getElementById(id), <span style="color: #0000ff;">this</span><span style="color: #000000;">);
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 编译完成后，将dom返回到app中。</span>
<span style="color: #000000;">            document.getElementById(id).appendChild(dom);
        }

        </span><span style="color: #0000ff;">var</span> vm  = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Vue({
            el: </span><span style="color: #800000;">'</span><span style="color: #800000;">app</span><span style="color: #800000;">'</span><span style="color: #000000;">,
            data: {
                text: </span><span style="color: #800000;">'</span><span style="color: #800000;">hello world</span><span style="color: #800000;">'</span><span style="color: #000000;">
            }
        });

    </span>&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/copycode.gif" alt="复制代码" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></a></span></div></div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>　　</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>参考文章：&nbsp;</p>
<ul>
<li>
<p class="postTitle"><a id="cb_post_title_url" class="postTitle2" href="http://www.cnblogs.com/kidney/p/6052935.html">Vue.js双向绑定的实现原理</a></p>
</li>
<li>
<p class="gh-header-title"><a href="https://github.com/DDFE/DDFE-blog/issues/7" target="_blank"><span class="js-issue-title">Vue 源码解析：深入响应式原理</span></a></p>
</li>
<li>
<p><a id="cb_post_title_url" href="http://www.cnblogs.com/canfoo/p/6891868.html">vue的双向绑定原理及实现</a></p>
</li>
</ul>
</div>
<div id="MySignature"></div>
<div class="clear"></div>
<div id="blog_post_info_block"><div id="BlogPostCategory">
    分类: 
            <a href="https://www.cnblogs.com/zhuzhenwei918/category/938372.html" target="_blank">vue</a></div>


    <div id="blog_post_info">
<div id="green_channel">
        <a href="javascript:void(0);" id="green_channel_digg" onclick="DiggIt(7309604,cb_blogId,1);green_channel_success(this,&#39;谢谢推荐！&#39;);">好文要顶</a>
        <a id="green_channel_follow" onclick="follow(&#39;2981eafc-1a94-e611-845c-ac853d9f53ac&#39;);" href="javascript:void(0);">关注我</a>
    <a id="green_channel_favorite" onclick="AddToWz(cb_entryId);return false;" href="javascript:void(0);">收藏该文</a>
    <a id="green_channel_weibo" href="javascript:void(0);" title="分享至新浪微博" onclick="ShareToTsina()"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/icon_weibo_24.png" alt=""></a>
    <a id="green_channel_wechat" href="javascript:void(0);" title="分享至微信" onclick="shareOnWechat()"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/wechat.png" alt=""></a>
</div>
<div id="author_profile">
    <div id="author_profile_info" class="author_profile_info">
            <a href="https://home.cnblogs.com/u/zhuzhenwei918/" target="_blank"><img src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/20161018223617.png" class="author_avatar" alt=""></a>
        <div id="author_profile_detail" class="author_profile_info">
            <a href="https://home.cnblogs.com/u/zhuzhenwei918/">Wayne-Zhu</a><br>
            <a href="https://home.cnblogs.com/u/zhuzhenwei918/followees/">关注 - 42</a><br>
            <a href="https://home.cnblogs.com/u/zhuzhenwei918/followers/">粉丝 - 303</a>
        </div>
    </div>
    <div class="clear"></div>
    <div id="author_profile_honor"></div>
    <div id="author_profile_follow">
                <a href="javascript:void(0);" onclick="follow(&#39;2981eafc-1a94-e611-845c-ac853d9f53ac&#39;);return false;">+加关注</a>
    </div>
</div>
<div id="div_digg">
    <div class="diggit" onclick="votePost(7309604,&#39;Digg&#39;)">
        <span class="diggnum" id="digg_count">1</span>
    </div>
    <div class="buryit" onclick="votePost(7309604,&#39;Bury&#39;)">
        <span class="burynum" id="bury_count">0</span>
    </div>
    <div class="clear"></div>
    <div class="diggword" id="digg_tips">
    </div>
</div>

<script type="text/javascript">
    currentDiggType = 0;
</script></div>
    <div class="clear"></div>
    <div id="post_next_prev">

    <a href="https://www.cnblogs.com/zhuzhenwei918/p/7289205.html" class="p_n_p_prefix">« </a> 上一篇：    <a href="https://www.cnblogs.com/zhuzhenwei918/p/7289205.html" title="发布于 2017-08-05 09:13">前端模板的原理与实现</a>
    <br>
    <a href="https://www.cnblogs.com/zhuzhenwei918/p/7339789.html" class="p_n_p_prefix">» </a> 下一篇：    <a href="https://www.cnblogs.com/zhuzhenwei918/p/7339789.html" title="发布于 2017-08-10 16:01">如何对react进行性能优化</a>

</div>
</div>
            </div>
            <div class="postDesc">posted @ 
<span id="post-date">2017-08-08 23:27</span>&nbsp;<a href="https://www.cnblogs.com/zhuzhenwei918/">Wayne-Zhu</a> 阅读(<span id="post_view_count">30251</span>) 评论(<span id="post_comment_count">1</span>) <a href="https://i.cnblogs.com/EditPosts.aspx?postid=7309604" rel="nofollow"> 编辑</a> <a href="javascript:void(0)" onclick="AddToWz(7309604); return false;">收藏</a>
</div>
        </div>
	    
	    
    </div><!--end: topics 文章、评论容器-->
</div>
<script src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/highlight.min.js.下载"></script>
<script>markdown_highlight();</script>
<script>
    var allowComments = true, cb_blogId = 311524, cb_blogApp = 'zhuzhenwei918', cb_blogUserGuid = '2981eafc-1a94-e611-845c-ac853d9f53ac';
    var cb_entryId = 7309604, cb_entryCreatedDate = '2017-08-08 23:27', cb_postType = 1; 
    loadViewCount(cb_entryId);
</script><a name="!comments"></a>
<div id="blog-comments-placeholder">

<div id="comment_pager_top">
    
</div>

<br>
<div class="feedback_area_title">评论列表</div>
<div class="feedbackNoItems"><div class="feedbackNoItems"></div></div>	
		<div class="feedbackItem eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);">
			<div class="feedbackListSubtitle">
				<div class="feedbackManage">
					&nbsp;&nbsp;

<span class="comment_actions">
    
    
    
    
</span>


				</div>
				
<a href="https://www.cnblogs.com/zhuzhenwei918/p/7309604.html#4234037" class="layer">#1楼</a>
<a name="4234037" id="comment_anchor_4234037"></a>

        <span id="comment-maxId" style="display:none">4234037</span>
        <span id="comment-maxDate" style="display:none">2019/4/18 上午9:59:14</span>
 
<span class="comment_date">2019-04-18 09:59</span>

 

            <a id="a_comment_author_4234037" href="https://www.cnblogs.com/zhurong/" target="_blank">漠里</a>

			</div>
			<div class="feedbackCon eye-protector-processed" style="border-bottom-color: rgba(0, 0, 0, 0.35);">
				
<div id="comment_body_4234037" class="blog_comment_body">
    从“六、响应式的数据绑定”向后 中的代码：vm[name]，应该是：vm.data[name]
</div>
        <div class="comment_vote">
            <a href="javascript:void(0);" class="comment_digg" onclick="return voteComment(&#39;4234037&#39;, &#39;Digg&#39;, this);">
                支持(0)
            </a>
            <a href="javascript:void(0);" class="comment_burry" onclick="return voteComment(&#39;4234037&#39;, &#39;Bury&#39;, this);">
                反对(0)
            </a>
        </div>
        <span id="comment_4234037_avatar" style="display:none">
            https://pic.cnblogs.com/face/592961/20180802101346.png
        </span>

			</div>
		</div>

<div id="comment_pager_bottom">
    
</div>


</div>
<script>
    var commentManager = new blogCommentManager();
    commentManager.renderComments(0);
</script>

<div id="comment_form" class="commentform">
    <a name="commentform"></a>
    <div id="divCommentShow"></div>
    <div id="comment_nav"><span id="span_refresh_tips"></span><a href="javascript:void(0);" onclick="return RefreshCommentList();" id="lnk_RefreshComments" runat="server" clientidmode="Static">刷新评论</a><a href="https://www.cnblogs.com/zhuzhenwei918/p/7309604.html#" onclick="return RefreshPage();">刷新页面</a><a href="https://www.cnblogs.com/zhuzhenwei918/p/7309604.html#top">返回顶部</a></div>
    <div id="comment_form_container" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"><div class="login_tips">
    注册用户登录后才能发表评论，请 
    <a rel="nofollow" href="javascript:void(0);" class="underline" onclick="return login(&#39;commentform&#39;);">登录</a>
     或 
    <a rel="nofollow" href="javascript:void(0);" class="underline" onclick="return register();">注册</a>，
    <a href="https://www.cnblogs.com/">访问</a> 网站首页。
</div></div>
    <div class="ad_text_commentbox" id="ad_text_under_commentbox"></div>
    <div id="ad_t2"><a href="http://www.ucancode.com/index.htm" target="_blank" onclick="ga(&#39;send&#39;, &#39;event&#39;, &#39;Link&#39;, &#39;click&#39;, &#39;T2-工控&#39;)">【推荐】超50万C++/C#源码: 大型实时仿真组态图形源码</a><br><a href="http://clickc.admaster.com.cn/c/a131574,b3595115,c1705,i0,m101,8a1,8b3,h" target="_blank" onclick="ga(&#39;send&#39;, &#39;event&#39;, &#39;Link&#39;, &#39;click&#39;, &#39;T2-华为云微认证&#39;)">【推荐】零基础轻松玩转云上产品，获壕礼加返百元大礼</a><br><a href="http://clickc.admaster.com.cn/c/a131575,b3595121,c1705,i0,m101,8a1,8b3,h" target="_blank" onclick="ga(&#39;send&#39;, &#39;event&#39;, &#39;Link&#39;, &#39;click&#39;, &#39;T2-物联网&#39;)">【推荐】华为IoT平台开发者套餐9.9元起，购买即送免费课程</a><br></div>
    <div id="opt_under_post"></div>
    <script async="async" src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/gpt.js.下载"></script>
    <script>
        var googletag = googletag || {};
        googletag.cmd = googletag.cmd || [];
    </script>
    <script>
        googletag.cmd.push(function () {
            googletag.defineSlot("/1090369/C1", [300, 250], "div-gpt-ad-1546353474406-0").addService(googletag.pubads());
            googletag.defineSlot("/1090369/C2", [468, 60], "div-gpt-ad-1539008685004-0").addService(googletag.pubads());
            googletag.pubads().enableSingleRequest();
            googletag.enableServices();
        });
    </script>
    <div id="cnblogs_c1" class="c_ad_block">
        <div id="div-gpt-ad-1546353474406-0" style="height:250px; width:300px;" data-google-query-id="CPnBxtaKouQCFZK7lgodvY0C6A"><div id="google_ads_iframe_/1090369/C1_0__container__" style="border: 0pt none;"><iframe id="google_ads_iframe_/1090369/C1_0" title="3rd party ad content" name="google_ads_iframe_/1090369/C1_0" width="300" height="250" scrolling="no" marginwidth="0" marginheight="0" frameborder="0" style="border: 0px; vertical-align: bottom;" data-google-container-id="1" data-load-complete="true" src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/saved_resource.html"></iframe></div></div>
    </div>
    <div id="under_post_news"><div class="recomm-block"><b>相关博文：</b><br>·  <a title="Vue.js双向绑定的实现原理" href="https://www.cnblogs.com/Mr-liyang/p/7728175.html" target="_blank" onclick="clickRecomItmem(7728175)">Vue.js双向绑定的实现原理</a><br>·  <a title="Vue.js双向绑定的实现原理" href="https://www.cnblogs.com/kidney/p/6052935.html" target="_blank" onclick="clickRecomItmem(6052935)">Vue.js双向绑定的实现原理</a><br>·  <a title="Vue.js双向绑定原理" href="https://www.cnblogs.com/fengxiongZz/p/8120337.html" target="_blank" onclick="clickRecomItmem(8120337)">Vue.js双向绑定原理</a><br>·  <a title="Vue.js双向绑定的实现原理" href="https://www.cnblogs.com/hekai123/p/7571744.html" target="_blank" onclick="clickRecomItmem(7571744)">Vue.js双向绑定的实现原理</a><br>·  <a title="Vue.js双向绑定的实现原理" href="https://www.cnblogs.com/libin-1/p/6833432.html" target="_blank" onclick="clickRecomItmem(6833432)">Vue.js双向绑定的实现原理</a><br></div></div>
    <div id="cnblogs_c2" class="c_ad_block">
        <div id="div-gpt-ad-1539008685004-0" style="height:60px; width:468px;" data-google-query-id="CPrBxtaKouQCFZK7lgodvY0C6A">
            
        <div id="google_ads_iframe_/1090369/C2_0__container__" style="border: 0pt none;"><iframe id="google_ads_iframe_/1090369/C2_0" title="3rd party ad content" name="google_ads_iframe_/1090369/C2_0" width="468" height="60" scrolling="no" marginwidth="0" marginheight="0" frameborder="0" style="border: 0px; vertical-align: bottom;" data-google-container-id="2" data-load-complete="true" src="./vue中的双向数据绑定详解 - Wayne-Zhu - 博客园_files/saved_resource(1).html"></iframe></div></div>
    </div>
    <div id="under_post_kb">
<div class="itnews c_ad_block">
    <b>最新 IT 新闻</b>:
    <br>
 ·              <a href="https://news.cnblogs.com/n/630205/" target="_blank">福特高管：自动驾驶汽车仅四年寿命 不会取代人类驾驶地位</a>
            <br>
 ·              <a href="https://news.cnblogs.com/n/630203/" target="_blank">行贿案裁决临近 三星李在镕或被剥夺缓刑资格</a>
            <br>
 ·              <a href="https://news.cnblogs.com/n/630202/" target="_blank">传华为将卖36万台俄版系统平板给俄罗斯：做人口普查</a>
            <br>
 ·              <a href="https://news.cnblogs.com/n/630201/" target="_blank">《魔兽世界》怀旧服正式开服！</a>
            <br>
 ·              <a href="https://news.cnblogs.com/n/630200/" target="_blank">充甲醇一分钟，通话一星期？</a>
            <br>
    » <a href="https://news.cnblogs.com/" title="IT 新闻" target="_blank">更多新闻...</a>
</div></div>
    <div id="HistoryToday" class="c_ad_block"></div>
    <script type="text/javascript">
        fixPostBody();
        setTimeout(function () { incrementViewCount(cb_entryId); }, 50);
        deliverAdT2();
        deliverAdC1();
        deliverAdC2();
        loadNewsAndKb();
        loadBlogSignature();
LoadPostCategoriesTags(cb_blogId, cb_entryId);        LoadPostInfoBlock(cb_blogId, cb_entryId, cb_blogApp, cb_blogUserGuid);
        GetPrevNextPost(cb_entryId, cb_blogId, cb_entryCreatedDate, cb_postType);
        loadOptUnderPost();
        GetHistoryToday(cb_blogId, cb_blogApp, cb_entryCreatedDate);
    </script>
</div>
	</div><!--end: forFlow -->
	</div><!--end: mainContent 主体内容容器-->

	<div id="sideBar">
		<div id="sideBarMain">
			


			<div id="blog-calendar" style="display: none; transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);" class="eye-protector-processed"></div><script>loadBlogDefaultCalendar();</script>
			
			<div id="leftcontentcontainer">
				<div id="blog-sidecolumn">

<!-- 搜索 -->
<div id="sidebar_search" class="sidebar-block">
    <div id="sidebar_search" class="mySearch eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);">
        <h3 class="catListTitle eye-protector-processed" style="border-bottom-color: rgba(0, 0, 0, 0.35);">搜索</h3>
        <div id="sidebar_search_box">
            <div id="widget_my_zzk" class="div_my_zzk">
                <input type="text" id="q" onkeydown="return zzk_go_enter(event);" class="input_my_zzk eye-protector-processed" style="border-color: rgba(0, 0, 0, 0.35);">&nbsp;<input onclick="zzk_go()" type="button" value="找找看" id="btnZzk" class="btn_my_zzk eye-protector-processed" style="border-color: rgba(0, 0, 0, 0.35);">
            </div>
            <div id="widget_my_google" class="div_my_zzk">
                <input type="text" name="google_q" id="google_q" onkeydown="return google_go_enter(event);" class="input_my_zzk eye-protector-processed" style="border-color: rgba(0, 0, 0, 0.35);">&nbsp;<input onclick="google_go()" type="button" value="谷歌搜索" class="btn_my_zzk eye-protector-processed" style="border-color: rgba(0, 0, 0, 0.35);">
            </div>
        </div>
    </div>
</div>

<!-- 常用链接 -->


<!-- 最新随笔 -->



<!-- 我的标签 -->
<div id="sidebar_toptags" class="sidebar-block">
    
</div>

<!-- 积分与排名 -->
<div id="sidebar_scorerank" class="sidebar-block">
    <div class="catListBlogRank eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);">
<h3 class="catListTitle eye-protector-processed" style="border-bottom-color: rgba(0, 0, 0, 0.35);">积分与排名</h3>
<ul>
	<li class="liScore">
		积分 -	
459130
	</li>
	<li class="liRank">
		排名 -	
474
	</li>
</ul>
</div>




</div>

<!-- 随笔分类、随笔档案、文章分类、新闻分类、相册、链接 -->
<div id="sidebar_categories">
    
        <div id="sidebar_postcategory" class="catListPostCategory sidebar-block eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);">
            <h3 class="catListTitle eye-protector-processed" style="border-bottom-color: rgba(0, 0, 0, 0.35);">
                

随笔分类



            </h3>


            <ul>

                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/915670.html" rel="">
    Ajax(3)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/1034379.html" rel="">
    Angular(1)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/928967.html" rel="">
    Bootstrap(1)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/1066684.html" rel="">
    C/C++(30)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/990545.html" rel="">
    cars(2)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/918795.html" rel="">
    chrome(7)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/1009476.html" rel="">
    computer problems &amp;&amp; solutions(5)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/899004.html" rel="">
    CSS3(11)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/993105.html" rel="">
    DOS(3)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/1032922.html" rel="">
    Electron(1)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/918655.html" rel="">
    ES6(7)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/1032931.html" rel="">
    flow.js / typescript(2)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/1208919.html" rel="">
    fortran(1)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/951939.html" rel="">
    git&amp;&amp;svn(6)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/907853.html" rel="">
    HTML&amp;CSS(48)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/899005.html" rel="">
    HTML5(14)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/1200015.html" rel="">
    java(7)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/896820.html" rel="">
    JavaScript(83)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/902405.html" rel="">
    jQuery(5)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/899006.html" rel="">
    JSON&amp;&amp;XML(4)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/1202887.html" rel="">
    Machine Learning(3)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/1116914.html" rel="">
    mgp(8)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/953565.html" rel="">
    node(22)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/905536.html" rel="">
    photoshop与切图(3)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/915109.html" rel="">
    PHP(2)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/1182604.html" rel="">
    python(4)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/939869.html" rel="">
    React(22)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/925539.html" rel="">
    Regular Expression(4)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/919426.html" rel="">
    sass/less(4)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/938372.html" rel="">
    vue(38)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/1062405.html" rel="">
    web安全(2)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/998212.html" rel="">
    wechat(4)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/912921.html" rel="">
    产品(10)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/913017.html" rel="">
    常用软件和插件(10)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/908151.html" rel="">
    关于前端(19)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/902747.html" rel="">
    计算机(12)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/970716.html" rel="">
    计算机专业基础(24)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/963411.html" rel="">
    可视化(11)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/1003115.html" rel="">
    前端工程化(11)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/920490.html" rel="">
    前端性能优化/效率(17)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/1000011.html" rel="">
    前后端分离(3)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/905249.html" rel="">
    实例(4)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/985522.html" rel="">
    数据库(8)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/911833.html" rel="">
    网站记录(4)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/914750.html" rel="">
    问题记录(16)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/911761.html" rel="">
    移动端(11)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/951351.html" rel="">
    用户体验(8)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/923723.html" rel="">
    杂文(46)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/category/950825.html" rel="">
    转载文章(12)
</a>
 

                        </li>

            </ul>


        </div>
        <div id="sidebar_postarchive" class="catListPostArchive sidebar-block eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);">
            <h3 class="catListTitle eye-protector-processed" style="border-bottom-color: rgba(0, 0, 0, 0.35);">
                

随笔档案



            </h3>


            <ul>

                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2019/01.html" rel="">
    2019年1月(1)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2018/12.html" rel="">
    2018年12月(3)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2018/11.html" rel="">
    2018年11月(1)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2018/10.html" rel="">
    2018年10月(2)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2018/07.html" rel="">
    2018年7月(3)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2018/06.html" rel="">
    2018年6月(6)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2018/05.html" rel="">
    2018年5月(13)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2018/04.html" rel="">
    2018年4月(25)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2018/03.html" rel="">
    2018年3月(19)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2017/12.html" rel="">
    2017年12月(5)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2017/11.html" rel="">
    2017年11月(14)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2017/10.html" rel="">
    2017年10月(11)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2017/09.html" rel="">
    2017年9月(16)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2017/08.html" rel="">
    2017年8月(35)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2017/07.html" rel="">
    2017年7月(38)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2017/06.html" rel="">
    2017年6月(32)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2017/05.html" rel="">
    2017年5月(76)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2017/04.html" rel="">
    2017年4月(35)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2017/03.html" rel="">
    2017年3月(32)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2017/02.html" rel="">
    2017年2月(48)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2017/01.html" rel="">
    2017年1月(15)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2016/12.html" rel="">
    2016年12月(43)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2016/11.html" rel="">
    2016年11月(37)
</a>
 

                        </li>
                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/archive/2016/10.html" rel="">
    2016年10月(14)
</a>
 

                        </li>

            </ul>


        </div>
        <div id="sidebar_imagecategory" class="catListImageCategory sidebar-block eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);">
            <h3 class="catListTitle eye-protector-processed" style="border-bottom-color: rgba(0, 0, 0, 0.35);">
                

相册



            </h3>


            <ul>

                        <li>
                            
<a href="https://www.cnblogs.com/zhuzhenwei918/gallery/1010047.html" rel="nofollow">
    photos(1)
</a>
 

                        </li>

            </ul>


        </div>

</div>

<!-- 最新评论 -->
<div id="sidebar_recentcomments" class="sidebar-block">
    <div class="catListComment eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);">
<h3 class="catListTitle eye-protector-processed" style="border-bottom-color: rgba(0, 0, 0, 0.35);">最新评论</h3>

	<div class="RecentCommentBlock">
        <ul>
                    <li class="recent_comment_title"><a href="https://www.cnblogs.com/zhuzhenwei918/p/6416880.html#4300445">1. Re:原生js实现轮播图</a></li>
                    <li class="recent_comment_body">@ 少年郎-权你说的没错，我也遇到了这个问题，wrap.style.left确实只能读写内联样式，但其实楼主是给了container一个内联的left:-600px的样式的。你可以楼主给的github...</li>
                    <li class="recent_comment_author">--joelhaha</li>
                    <li class="recent_comment_title"><a href="https://www.cnblogs.com/zhuzhenwei918/p/7465467.html#4288060">2. Re:TCP为什么是三次握手，为什么不是两次或者四次 &amp;&amp; TCP四次挥手</a></li>
                    <li class="recent_comment_body">为什么不是 2次？？ 问的太笼统   具体少了哪次？？  你不知道少了哪次就分析出答案来了？？</li>
                    <li class="recent_comment_author">--ssif</li>
                    <li class="recent_comment_title"><a href="https://www.cnblogs.com/zhuzhenwei918/p/9057289.html#4282038">3. Re:vscode下调试运行c++</a></li>
                    <li class="recent_comment_body">task.json这个文件有些古老了，现在vscode都是允许定义多个task</li>
                    <li class="recent_comment_author">--weiyinfu</li>
                    <li class="recent_comment_title"><a href="https://www.cnblogs.com/zhuzhenwei918/p/6866094.html#4279223">4. Re:为什么vue+webpack需要用到node，如何部署项目到服务器？</a></li>
                    <li class="recent_comment_body">开启支.htaccess文件支持<br>这个.htaccess是在哪儿设置的呀？</li>
                    <li class="recent_comment_author">--ykCoder</li>
                    <li class="recent_comment_title"><a href="https://www.cnblogs.com/zhuzhenwei918/p/6866094.html#4279222">5. Re:为什么vue+webpack需要用到node，如何部署项目到服务器？</a></li>
                    <li class="recent_comment_body">开启支.htaccess文件支持</li>
                    <li class="recent_comment_author">--ykCoder</li>
        </ul>
    </div>
</div>


</div>



<!-- 阅读排行榜 -->
<div id="sidebar_topviewedposts" class="sidebar-block">
    <div class="catListView eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);">
<h3 class="catListTitle eye-protector-processed" style="border-bottom-color: rgba(0, 0, 0, 0.35);">阅读排行榜</h3>
	<div id="TopViewPostsBlock">
        <ul style="word-break:break-all">
                    <li>
                        <a href="https://www.cnblogs.com/zhuzhenwei918/p/6416880.html">
                            1. 原生js实现轮播图(77257)
                        </a>
                    </li>
                    <li>
                        <a href="https://www.cnblogs.com/zhuzhenwei918/p/6198821.html">
                            2. 正则表达式之数字验证(62597)
                        </a>
                    </li>
                    <li>
                        <a href="https://www.cnblogs.com/zhuzhenwei918/p/7582620.html">
                            3. 状态码301和302的区别(56305)
                        </a>
                    </li>
                    <li>
                        <a href="https://www.cnblogs.com/zhuzhenwei918/p/9057289.html">
                            4. vscode下调试运行c++(51750)
                        </a>
                    </li>
                    <li>
                        <a href="https://www.cnblogs.com/zhuzhenwei918/p/6892066.html">
                            5. 如何去除vue项目中的 # --- History模式(48843)
                        </a>
                    </li>
        </ul>
    </div>
</div>


</div>

<!-- 评论排行榜 -->
<div id="sidebar_topcommentedposts" class="sidebar-block">
    <div class="catListFeedback eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);">
<h3 class="catListTitle eye-protector-processed" style="border-bottom-color: rgba(0, 0, 0, 0.35);">评论排行榜</h3>
	<div id="TopFeedbackPostsBlock">
        <ul style="word-break:break-all">
                    <li>
                        <a href="https://www.cnblogs.com/zhuzhenwei918/p/6181760.html">
                            1. jQuery中的100个技巧（译）(27)
                        </a>
                    </li>
                    <li>
                        <a href="https://www.cnblogs.com/zhuzhenwei918/p/6416880.html">
                            2. 原生js实现轮播图(24)
                        </a>
                    </li>
                    <li>
                        <a href="https://www.cnblogs.com/zhuzhenwei918/p/7732819.html">
                            3. 总结(20)
                        </a>
                    </li>
                    <li>
                        <a href="https://www.cnblogs.com/zhuzhenwei918/p/6124263.html">
                            4. 深入理解css中的margin属性(13)
                        </a>
                    </li>
                    <li>
                        <a href="https://www.cnblogs.com/zhuzhenwei918/p/6112034.html">
                            5. 深入理解css中position属性及z-index属性(9)
                        </a>
                    </li>
        </ul>
    </div>
</div>


</div>

<!-- 推荐排行榜 -->
<div id="sidebar_topdiggedposts" class="sidebar-block">
    
<div id="topdigg_posts_wrap">
    <div class="catListView eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);">
        <h3 class="catListTitle eye-protector-processed" style="border-bottom-color: rgba(0, 0, 0, 0.35);">推荐排行榜</h3>
        <div id="TopDiggPostsBlock">
            <ul style="word-break: break-all">
                        <li>
                            <a href="https://www.cnblogs.com/zhuzhenwei918/p/6181760.html">
                                1. jQuery中的100个技巧（译）(28)
                            </a>
                        </li>
                        <li>
                            <a href="https://www.cnblogs.com/zhuzhenwei918/p/6416880.html">
                                2. 原生js实现轮播图(21)
                            </a>
                        </li>
                        <li>
                            <a href="https://www.cnblogs.com/zhuzhenwei918/p/6112034.html">
                                3. 深入理解css中position属性及z-index属性(21)
                            </a>
                        </li>
                        <li>
                            <a href="https://www.cnblogs.com/zhuzhenwei918/p/7732819.html">
                                4. 总结(20)
                            </a>
                        </li>
                        <li>
                            <a href="https://www.cnblogs.com/zhuzhenwei918/p/6104065.html">
                                5. 如何写出优雅的css代码 ？(13)
                            </a>
                        </li>
            </ul>
        </div>
    </div>
</div>
</div></div>
                    <script>loadBlogSideColumn();</script>
			</div>
			
		</div><!--end: sideBarMain -->
	</div><!--end: sideBar 侧边栏容器 -->
	<div class="clear"></div>
	</div><!--end: main -->
	<div class="clear"></div>
	<div id="footer">
		<!--done-->
Copyright © 2019 Wayne-Zhu
<br><span id="poweredby">Powered by .NET Core 3.0 Preview 8 on Linux</span>



	</div><!--end: footer -->
</div><!--end: home 自定义的最大容器 -->


    <div id="page_end_html">
        <h3 style="padding: 8px; text-indent: 2em">一分耕耘，一分收获。</h3>
    </div>


<div style="position: static; width: 0px; height: 0px; border: none; padding: 0px; margin: 0px;"><div id="trans-tooltip"><div id="tip-left-top" style="background: url(&quot;chrome-extension://ccfjcepmiaackkccabgeeegeklgifffd/imgs/map/tip-left-top.png&quot;);"></div><div id="tip-top" style="background: url(&quot;chrome-extension://ccfjcepmiaackkccabgeeegeklgifffd/imgs/map/tip-top.png&quot;) repeat-x;"></div><div id="tip-right-top" style="background: url(&quot;chrome-extension://ccfjcepmiaackkccabgeeegeklgifffd/imgs/map/tip-right-top.png&quot;);"></div><div id="tip-right" style="background: url(&quot;chrome-extension://ccfjcepmiaackkccabgeeegeklgifffd/imgs/map/tip-right.png&quot;) repeat-y;"></div><div id="tip-right-bottom" style="background: url(&quot;chrome-extension://ccfjcepmiaackkccabgeeegeklgifffd/imgs/map/tip-right-bottom.png&quot;);"></div><div id="tip-bottom" style="background: url(&quot;chrome-extension://ccfjcepmiaackkccabgeeegeklgifffd/imgs/map/tip-bottom.png&quot;) repeat-x;"></div><div id="tip-left-bottom" style="background: url(&quot;chrome-extension://ccfjcepmiaackkccabgeeegeklgifffd/imgs/map/tip-left-bottom.png&quot;);"></div><div id="tip-left" style="background: url(&quot;chrome-extension://ccfjcepmiaackkccabgeeegeklgifffd/imgs/map/tip-left.png&quot;);"></div><div id="trans-content" class="eye-protector-processed" style="transition: background-color 0.3s ease 0s; background-color: rgb(193, 230, 198);"></div></div><div id="tip-arrow-bottom" style="background: url(&quot;chrome-extension://ccfjcepmiaackkccabgeeegeklgifffd/imgs/map/tip-arrow-bottom.png&quot;);"></div><div id="tip-arrow-top" style="background: url(&quot;chrome-extension://ccfjcepmiaackkccabgeeegeklgifffd/imgs/map/tip-arrow-top.png&quot;);"></div></div></body></html>